package com.snow.student;

import com.snow.proto.*;
import io.grpc.stub.StreamObserver;

import java.util.UUID;

public class StudentServiceImpl extends StudentServiceGrpc.StudentServiceImplBase {
    @Override
    public void getRealNameByUsername(MyRequest request, StreamObserver<MyResponse> responseObserver) {
        System.out.println("------------------请求非流，响应非流：-------------------------");
        System.out.println("接收到客户端信息" + request.getUsername());

        responseObserver.onNext(MyResponse.newBuilder().setRealname("张三").build());
        responseObserver.onCompleted();
    }

    @Override
    public void getStudentsByAge(StudentRequest request, StreamObserver<StudentResponse> responseObserver) {
//        super.getStudentsByAge(request, responseObserver);
        System.out.println("------------------请求非流，响应为流：-------------------------");
        System.out.println("接收到客户端消息：" + request.getAge());

        responseObserver.onNext(StudentResponse.newBuilder().setName("张三").setAge(20).setCity("北京").build());
        responseObserver.onNext(StudentResponse.newBuilder().setName("李四").setAge(30).setCity("天津").build());
        try {
            // 加此句的目的是为了测试：
            // 服务端发送一次数据，客户端就接收一次数据；
            // 服务端发送一次数据，客户端就可以对这次数据进行处理，但无法对未发送的数据进行处理；
            // 当服务端休眠，客户端就会被阻塞，一直等待数据直到服务端调用onCompleted方法；但当客户端使用的是异步的stub，则不会发生。
            Thread.sleep(1000);
            // 当客户端调用一次迭代器的next，服务端才会返回一次数据，两端的next是相互对应的。
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        responseObserver.onNext(StudentResponse.newBuilder().setName("王五").setAge(40).setCity("成都").build());
        responseObserver.onNext(StudentResponse.newBuilder().setName("赵六").setAge(50).setCity("深圳").build());

        responseObserver.onCompleted();//一定要调用
    }

    @Override
    public StreamObserver<StudentRequest> getStudentsWrapperByAges(StreamObserver<StudentResponseList> responseObserver) {
//        return super.getStudentsWrapperByAges(responseObserver);
        System.out.println("------------------请求为流，响应非流，响应为集合：-------------------------");
        //以下是对请求的每一块进行的处理，以及完成之后构造一个集合发送到客户端：
        return new StreamObserver<StudentRequest>() {
            @Override
            public void onNext(StudentRequest value) {
                System.out.println("onNext: " + value.getAge());
//                try {
//                    Thread.sleep(5000);
//                } catch (InterruptedException e) {
//                    e.printStackTrace();
//                }
            }

            @Override
            public void onError(Throwable t) {
                System.out.println(t.getMessage());
            }

            @Override
            public void onCompleted() {
                StudentResponse studentResponse1 = StudentResponse.newBuilder().setName("张三").setAge(20).setCity("西安").build();
                StudentResponse studentResponse2 = StudentResponse.newBuilder().setName("李四").setAge(30).setCity("广州").build();

                StudentResponseList studentResponseList = StudentResponseList.newBuilder()
                        .addStudentResponse(studentResponse1)
                        .addStudentResponse(studentResponse2).build();

                responseObserver.onNext(studentResponseList);
                responseObserver.onCompleted();
            }
        };
    }

    @Override
    public StreamObserver<StreamRequest> biTalk(StreamObserver<StreamResponse> responseObserver) {
//        return super.biTalk(responseObserver);
        return new StreamObserver<StreamRequest>() {
            @Override
            public void onNext(StreamRequest value) {
                System.out.println(value.getRequestInfo());

                responseObserver.onNext(StreamResponse.newBuilder().setResponseInfo(
                        UUID.randomUUID().toString()
                    ).build());
            }

            @Override
            public void onError(Throwable t) {
                System.out.println(t.getMessage());
            }

            @Override
            public void onCompleted() {
                responseObserver.onCompleted();
            }
        };
    }
}
